<template>
    <SysDialog :title="dialog.title" :visible="dialog.visible" :width="dialog.width" :height="dialog.height"
        @onClose="onCloseDialog" @onConfirm="onConfirmDialog">
        <template v-slot:content>
            <el-form :model="articleModel" ref="articleRef" :rules="articleRules" label-width="85px" :inline="false">
                <el-form-item label="文章分类" prop="sort">
                    <el-tree-select v-model="articleModel.sort" :data="sortList" check-strictly>
                    </el-tree-select>
                </el-form-item>
                <el-form-item label="文章标题" prop="title">
                    <el-input v-model="articleModel.title"></el-input>
                </el-form-item>
                <el-form-item label="文章短标题" prop="shorter">
                    <el-input v-model="articleModel.shorter"></el-input>
                </el-form-item>
                <el-form-item label="关键字" prop="keywords">
                    <el-input v-model="articleModel.keywords" type="textarea"></el-input>
                </el-form-item>
                <el-form-item label="简介" prop="description">
                    <el-input v-model="articleModel.description" type="textarea"></el-input>
                </el-form-item>
                <el-form-item label="封面">
                    <el-upload class="avatar-uploader" :action="qiniuApi" :show-file-list="false" :data="pic.qiniuToken"
                        :on-success="handleAvatarSuccess" :on-progress="handlePreview"
                        :before-upload="beforeAvatarUpload" :on-error="handleError">
                        <img v-if="articleModel.pic" :src="articleModel.pic" class="avatar">
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>
                <el-form-item label="内容">
                    <div style="border: 1px solid #ccc">
                        <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef"
                            :defaultConfig="toolbarConfig" :mode="mode" />
                        <Editor style="height: 500px; overflow-y: hidden;" v-model="articleModel.content"
                            :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
                    </div>
                </el-form-item>
                <el-form-item>
                    是否发布&nbsp;:&nbsp;
                    <el-switch v-model="articleModel.is_active" inline-prompt active-text="发布" inactive-text="下架"
                        :width="50" />
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    是否推荐&nbsp;:&nbsp;
                    <el-switch v-model="articleModel.is_recommend" inline-prompt active-text="是" inactive-text="否"
                        :width="50" />
                </el-form-item>
            </el-form>
        </template>
    </SysDialog>
</template>

<script setup lang='ts'>
import { ref, reactive, onMounted } from 'vue'

import '@wangeditor/editor/dist/css/style.css'
import { ElForm, ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadFile, UploadFiles, UploadProps, UploadProgressEvent } from 'element-plus'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'

import SysDialog from '@/components/SysDialog.vue'
import useDialog, { DialogType } from '@/hooks/useDialog'
import useInstance from '@/hooks/useInstance'
import useWangEditor from '@/hooks/useWangEditor'
import useArticleModel, { IArticle } from '@/composables/article/useArticleModel'
import { postArticleApi, putArticleApi, getArticleDetailsApi } from '@/http/api/article'
import { getQiniuTokenApi } from '@/http/api/site'
import { qiniuCDN, qiniuApi } from '@/http'

const { editorRef, mode, toolbarConfig, editorConfig, handleCreated } = useWangEditor()
const { dialog, onShowDialog, onCloseDialog } = useDialog()
const { global } = useInstance()
const { iArticleModel, articleRules } = useArticleModel()

// 接受父组件传进来的数据
defineProps(['sortList'])
// 调用父组件方法
const emit = defineEmits(['newGetArticleList'])

// 菜单绑定数据
const articleModel = reactive<IArticle>(iArticleModel())
// 菜单ref属性
const articleRef = ref<InstanceType<typeof ElForm>>()
// 弹窗显示
const onShow = (dialogType: string, title: string, article_id?: number) => {
    global.$resetForm(articleRef.value, articleModel, iArticleModel)
    dialog.title = title
    dialog.width = '80%'
    dialog.height = '70vh'
    onShowDialog()
    if (article_id && dialogType == DialogType.EDIT) {
        getArticleDetailsApi(article_id).then(res => {
            if (res && res.code == 200) {
                Object.keys(articleModel).forEach(key => {
                    if (key != 'type') {
                        articleModel[key] = res.data[key]
                    }
                })
            }

        })
    }
    articleModel.type = dialogType
}
// 图片
const pic = reactive({
    qiniuToken: {}
})
// 获取七牛token
const getQiniuToken = async () => {
    await getQiniuTokenApi().then(res => {
        if (res && res.code == 200) {
            pic.qiniuToken = res.data
        }
    })
}
// 上传之前
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    const imgType = ['image/jpeg', 'image/png']
    if (imgType.indexOf(rawFile.type) == -1) {
        ElMessage.error('请勿上传图片以外的其他文件!')
        return false
    } else if (rawFile.size / 1024 / 1024 > 1) {
        ElMessage.error('请勿上传大于1M的图片!')
        return false
    }
    return true
}
// 进度条
const percentage = ref(0)
// 上传时
const handlePreview: UploadProps['onProgress'] = (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
    percentage.value = (evt.loaded / evt.total * 100) | 0
}
// 图片上传成功后
const handleAvatarSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
    articleModel.pic = qiniuCDN + response.key
}
// 上传失败后
const handleError = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
    ElMessage.error('上传失败,请重新上传!')
}
// 弹窗确定
const onConfirmDialog = () => {
    articleRef.value?.validate(valid => {
        if (valid) {
            if (articleModel.type == DialogType.ADD) {
                addMenu(articleModel)
            }
            if (articleModel.type == DialogType.EDIT) {
                editMenu(articleModel)
            }
        }
    })
}
// 添加菜单
const addMenu = async (menuModel: IArticle) => {
    await postArticleApi(menuModel).then(res => {
        if (res && res.code == 201) {
            ElMessage.success('添加成功！')
            emit('newGetArticleList')
            global.$resetForm(articleRef.value, menuModel, iArticleModel)
            onCloseDialog()
        } else {
            ElMessage.error(res.msg)
        }
    })
}
// 修改菜单
const editMenu = async (menuModel: IArticle) => {
    await putArticleApi(menuModel.id, menuModel).then(res => {
        if (res && res.code == 202) {
            ElMessage.success('修改成功！')
            emit('newGetArticleList')
            global.$resetForm(articleRef.value, menuModel, iArticleModel)
            onCloseDialog()
        } else {
            ElMessage.error(res.msg)
        }
    })
}

onMounted(() => {
    getQiniuToken()
})

// 暴露法方给父组件
defineExpose({ onShow })

</script>

<style scoped lang='scss'>
:deep(.avatar-uploader) {
    .el-upload {
        border: 1px dashed #dcdfe6;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: .2s;
    }

    .avatar-uploader .el-upload:hover {
        border-color: #3375b9;
    }

    .el-icon.avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 50px;
        height: 50px;
        text-align: center;
    }

    img {
        max-height: 100px;
    }

}
</style>